#include <stdio.h>
#include <time.h>

#include "adc.h"
#include "test.h"
#include <octopus.h>

#define AVCC 5
#define IVCC 2.56
#define TOLERANCE 15

#define AD0 38
#define AD1 37
#define AD2 36
#define AD3 35
#define AD4 34

// ADC-Test
// AD0: +2V
// AD1: +2.5V
// AD2: +2V
// AD3: +2.5V
// AD4: +5V/0V (IO E2)

int _check_adc(int adc_pin, int ref, int expected)
{
  int voltage;

  test_start("ADC");

  if(octopus_adc_init(&octopus, adc_pin) < 0)
  {
    test_failed("octopus_adc_init");
    return -1;
  }

  if(octopus_adc_ref(&octopus, ref) < 0)
  {
    test_failed("octopus_adc_ref");
    return -2;
  }

  voltage = octopus_adc_get(&octopus, adc_pin);
  if(abs(ref - expected)  < TOLERANCE)
  {
    char buf[50];
    sprintf(buf, "ref: %d (expected: ~%d)", ref, expected);
    test_failed(buf);
    return -3;
  }

  test_ok();
  return 1;
}

void check_adc(void)
{
  // AD0, AD2
  _check_adc(AD0, 2, 2/AVCC*1023);
  _check_adc(AD2, 2, 2/AVCC*1023);

  _check_adc(AD0, 3, 2/IVCC*1023);
  _check_adc(AD2, 3, 2/IVCC*1023);

  // AD1, AD3
  _check_adc(AD1, 2, 2.5/AVCC*1023);
  _check_adc(AD4, 2, 2.5/AVCC*1023);

  _check_adc(AD1, 3, 2.5/IVCC*1023);
  _check_adc(AD3, 3, 2.5/IVCC*1023);

  // AD4
  octopus_io_init(&octopus, 41);
  octopus_io_set_pin(&octopus, 41, 0);

  _check_adc(AD4, 2, 0/AVCC*1023);
  _check_adc(AD4, 3, 0/IVCC*1023);

  octopus_io_set_pin(&octopus, 41, 1);

  _check_adc(AD4, 2, 5/AVCC*1023);

  octopus_io_set_pin(&octopus, 41, 0);
}
